<?php
namespace App\Lib\Consul;

use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\Annotation\Mapping\Inject;
use Swoft\Consul\Exception\ClientException;
use Swoft\Consul\Exception\ServerException;
use Swoft\Consul\Helper\OptionsResolver;

/**
 * Class ServiceSelector
 * @package App\Http\Lib
 * @Bean("ServiceSelector")
 */
class ServiceSelector
{

    /**
     * @Inject()
     * @var Agent
     */
    private $agent;

    /**
     * 根据服务名称获取服务列表
     * @param string $serviceName
     * @return array
     * @throws ClientException
     * @throws ServerException
     */
    public function services(string $serviceName = ''):array {

        if($serviceName){
            $services = $this->agent->services(['filter' => "Service==$serviceName"])->getResult();
        }
        else{
            $services = $this->agent->services()->getResult();
        }
        if(! empty($services)){
            $serviceIDS = $this->checks($serviceName);
            return array_values(OptionsResolver::resolve($services, $serviceIDS));
        }
        return [];
    }

    /**
     * 获取健康的服务信息
     * @param string $serviceName
     * @return array
     * @throws ClientException
     * @throws ServerException
     */
    protected function checks(string $serviceName=''):array {
        // 获取健康的服务列表
        $healths = $this->agent->checks(['filter' => 'Status==passing'])->getResult();
        /**
         * healths 的一个单元
        ["service:DBC7D58D-D85D-D882-82BD-F2E0B1AE463D"]=> array(13) {
        ["Node"]=> string(12) "f6b76db7ee61"
        ["CheckID"]=> string(44) "service:DBC7D58D-D85D-D882-82BD-F2E0B1AE463D"
        ["Name"]=> string(20) "Service 'Test' check"
        ["Status"]=> string(7) "passing"
        ["Notes"]=> string(0) ""
        ["Output"]=> string(72) "HTTP POST http://172.17.3.4:18306/health: 200 OK Output: {"Status":"ok"}"
        ["ServiceID"]=> string(36) "DBC7D58D-D85D-D882-82BD-F2E0B1AE463D"
        ["ServiceName"]=> string(4) "Test"
        ["ServiceTags"]=> array(1) {
        [0]=> string(4) "http"
        }
        ["Type"]=> string(4) "http"
        ["Definition"]=> array(0) {
        }
        ["CreateIndex"]=> int(0)
        ["ModifyIndex"]=> int(0)
        }
         */

        // 根据 serviceName 筛选出来 ServiceID 组成一个索引数组
        if(empty($serviceName)){
            //  如果服务名为空则筛选出所有的ID
            return array_column($healths, 'ServiceID');
        }

        // 如果服务名不为空则 根据服务名进行筛选动作
        $serviceIDS = [];
        foreach($healths as $item){
            if($item['ServiceName'] === $serviceName){
                $serviceIDS[] = $item['ServiceID'];
            }
        }
        return $serviceIDS;
    }

}
